# -*- coding: utf-8 -*-
# @Author  : longbhu
# @Time    : 2025/7/28 14:46
# @Function:
# 创建一个Redis连接包装器
# utils/redis.py
import redis
import json
# import urllib.parse
from functools import wraps
# from flask import current_app

class RedisClient:
    def __init__(self):
        self.client = None

    def init_app(self, app):
        self.client = redis.from_url(app.config['REDIS_URL'])

    def get(self, key):
        if not self.client:
            return None
        try:
            return self.client.get(key)
        except Exception:
            return None

    def setex(self, key, time, value):
        if not self.client:
            return False
        try:
            self.client.setex(key, time, value)
            return True
        except Exception:
            return False

    # 添加删除键的方法
    def delete(self, *keys):
        if not self.client:
            return 0
        try:
            return self.client.delete(*keys)
        except Exception:
            return 0

    # 添加设置键值的方法（无过期时间）
    def set(self, key, value):
        if not self.client:
            return False
        try:
            self.client.set(key, value)
            return True
        except Exception:
            return False

    # 添加检查键是否存在的方法
    def exists(self, key):
        if not self.client:
            return False
        try:
            return self.client.exists(key) > 0
        except Exception:
            return False

    # 添加设置过期时间的方法
    def expire(self, key, time):
        if not self.client:
            return False
        try:
            return self.client.expire(key, time)
        except Exception:
            return False

    # 添加获取所有匹配模式的键
    def keys(self, pattern="*"):
        if not self.client:
            return []
        try:
            return self.client.keys(pattern)
        except Exception:
            return []

    # 添加递增计数器方法
    def incr(self, key):
        if not self.client:
            return None
        try:
            return self.client.incr(key)
        except Exception:
            return None

    # 添加递减计数器方法
    def decr(self, key):
        if not self.client:
            return None
        try:
            return self.client.decr(key)
        except Exception:
            return None

# 创建全局 Redis 客户端实例
redis_client_instance = RedisClient()


def cache_result(expiration=3600):
    def decorator(func):
        @wraps(func)
        def wrapper(self, *args, **kwargs):
            # 确保 Redis 客户端可用
            if not redis_client_instance.client:
                print(f"Redis not initialized, executing {func.__name__} without cache")
                return func(self, *args, **kwargs)

            # 生成缓存键 - 使用 URL 编码处理特殊字符
            cache_key = f"{func.__name__}"
            if args:
                arg_str = ':'.join(str(arg) for arg in args)
                cache_key += f":{arg_str}"
            if kwargs:
                # 直接将关键字参数格式化为字符串并用冒号连接
                kwarg_str = ':'.join(f'{k}={v}' for k, v in kwargs.items())
                cache_key += f":{kwarg_str}"

            # if kwargs:
            #     kwarg_str = ':'.join(f'{k}={v}' for k, v in kwargs.items())
            #     # URL 编码处理特殊字符，包括中文
            #     kwarg_str = urllib.parse.quote(kwarg_str, safe=':')
            #     cache_key += f":{kwarg_str}"

            # 尝试获取缓存
            try:
                print(f"cache_result: {cache_key}")
                cached_result = redis_client_instance.get(cache_key)
                if cached_result:
                    print(f"Cache HIT for {cache_key}")
                    return json.loads(cached_result)
                else:
                    print(f"Cache MISS for {cache_key}")
            except Exception as e:
                print(f"Redis get error: {e}")

            # 执行原函数
            result = func(self, *args, **kwargs)
            print(f"Executed function {func.__name__} and got result")

            # 缓存结果
            try:
                if hasattr(result, '__dict__'):
                    # 处理 SQLAlchemy 对象
                    serializable_result = {}
                    for key, value in result.__dict__.items():
                        if not key.startswith('_'):  # 忽略私有属性
                            serializable_result[key] = value
                    redis_client_instance.setex(cache_key, expiration, json.dumps(serializable_result, default=str))
                elif isinstance(result, list):
                    # 处理对象列表
                    serializable_result = []
                    for item in result:
                        if hasattr(item, '__dict__'):
                            item_dict = {}
                            for key, value in item.__dict__.items():
                                if not key.startswith('_'):
                                    item_dict[key] = value
                            serializable_result.append(item_dict)
                        else:
                            serializable_result.append(item)
                    redis_client_instance.setex(cache_key, expiration, json.dumps(serializable_result, default=str))
                else:
                    # 处理普通对象
                    redis_client_instance.setex(cache_key, expiration, json.dumps(result, default=str))
                print(f"Result cached for {cache_key}")
            except Exception as e:
                print(f"Redis set error: {e}")

            return result
        return wrapper
    return decorator


# # 创建全局 Redis 客户端实例
# redis_client_instance = RedisClient()
#
#
# def cache_result(expiration=3600):
#     def decorator(func):
#         @wraps(func)
#         def wrapper(self, *args, **kwargs):
#             # 确保 Redis 客户端可用
#             if not redis_client_instance.client:
#                 print(f"Redis not initialized, executing {func.__name__} without cache")
#                 return func(self, *args, **kwargs)
#
#             # 生成缓存键 - 使用 URL 编码处理特殊字符
#             cache_key = f"{func.__name__}"
#             if args:
#                 arg_str = ':'.join(str(arg) for arg in args)
#                 cache_key += f":{arg_str}"
#             if kwargs:
#                 kwarg_str = ':'.join(f'{k}={v}' for k, v in kwargs.items())
#                 # URL 编码处理特殊字符，包括中文
#                 kwarg_str = urllib.parse.quote(kwarg_str, safe=':')
#                 cache_key += f":{kwarg_str}"
#
#             # 尝试获取缓存
#             try:
#                 print(f"cache_result: {cache_key}")
#                 cached_result = redis_client_instance.get(cache_key)
#                 if cached_result:
#                     print(f"Cache HIT for {cache_key}")
#                     return json.loads(cached_result)
#                 else:
#                     print(f"Cache MISS for {cache_key}")
#             except Exception as e:
#                 print(f"Redis get error: {e}")
#
#             # 执行原函数
#             result = func(self, *args, **kwargs)
#             print(f"Executed function {func.__name__} and got result")
#
#             # 缓存结果
#             try:
#                 if hasattr(result, '__dict__'):
#                     # 处理 SQLAlchemy 对象
#                     serializable_result = {}
#                     for key, value in result.__dict__.items():
#                         if not key.startswith('_'):  # 忽略私有属性
#                             serializable_result[key] = value
#                     redis_client_instance.setex(cache_key, expiration, json.dumps(serializable_result, default=str))
#                 elif isinstance(result, list):
#                     # 处理对象列表
#                     serializable_result = []
#                     for item in result:
#                         if hasattr(item, '__dict__'):
#                             item_dict = {}
#                             for key, value in item.__dict__.items():
#                                 if not key.startswith('_'):
#                                     item_dict[key] = value
#                             serializable_result.append(item_dict)
#                         else:
#                             serializable_result.append(item)
#                     redis_client_instance.setex(cache_key, expiration, json.dumps(serializable_result, default=str))
#                 else:
#                     # 处理普通对象
#                     redis_client_instance.setex(cache_key, expiration, json.dumps(result, default=str))
#                 print(f"Result cached for {cache_key}")
#             except Exception as e:
#                 print(f"Redis set error: {e}")
#
#             return result
#         return wrapper
#     return decorator
